import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.concurrent.Semaphore;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ReadAndWrite extends JFrame {
    public static Semaphore rw = new Semaphore(1);
    public static Semaphore mutex = new Semaphore(1);
    public static Semaphore w = new Semaphore(1);
    public static Semaphore fresh = new Semaphore(1);
    public static int count = 0;

    public static LinkedList<String> Re = new LinkedList<>();//读空间
    public static LinkedList<String> Wr = new LinkedList<>();//写空间
    public static LinkedList<String> ing = new LinkedList<>();//正在的状态

    private int reader = 0;//写者数量和编号记录
    private int writer = 0;//读者数量和编号记录

    //三个大的文本区域
    static JTextPane jTextPane1 = new JTextPane();//读
    static JTextPane jTextPane2 = new JTextPane();//文件
    static JTextPane jTextPane3 = new JTextPane();//写

    public ReadAndWrite(int a, int b) {
        super("小王读者写者问题");
        reader = a + 1;
        writer = b + 1;
        for (int i = 1; i <= a; i++)
            new Thread(new Read(i)).start();
        for (int i = 1; i <= b; i++)
            new Thread(new Write(i)).start();

        setBounds(400, 300, 700, 550);

        JPanel jPanel1 = new JPanel(new BorderLayout());//读
        JPanel jPanel2 = new JPanel(new BorderLayout());//临界区
        JPanel jPanel3 = new JPanel(new BorderLayout());//写
        jPanel1.setBackground(new Color(0x90D1FF));
        jPanel2.setBackground(new Color(0xFF9CD0));
        jPanel3.setBackground(new Color(0xB0DA8E));

        this.add(jPanel1, BorderLayout.WEST);
        this.add(jPanel2, BorderLayout.CENTER);
        this.add(jPanel3, BorderLayout.EAST);

        JLabel label1 = new JLabel("       读者       ");
        JLabel label2 = new JLabel("        临界区");
        JLabel label3 = new JLabel("       写者       ");
        label1.setFont(new Font("宋体", Font.BOLD, 20));
        label2.setFont(new Font("宋体", Font.BOLD, 20));
        label3.setFont(new Font("宋体", Font.BOLD, 20));

        jPanel1.add(label1, BorderLayout.NORTH);
        jPanel2.add(label2, BorderLayout.NORTH);
        jPanel3.add(label3, BorderLayout.NORTH);

        jTextPane1.setEditable(false);//禁止编辑
        jTextPane2.setEditable(false);
        jTextPane3.setEditable(false);

        jTextPane1.setFont(new Font("宋体", Font.BOLD, 16));
        jTextPane2.setFont(new Font("宋体", Font.BOLD, 16));
        jTextPane3.setFont(new Font("宋体", Font.BOLD, 16));

        jPanel1.add(new JScrollPane(jTextPane1), BorderLayout.CENTER);
        jPanel2.add(new JScrollPane(jTextPane2), BorderLayout.CENTER);
        jPanel3.add(new JScrollPane(jTextPane3), BorderLayout.CENTER);

        JButton jButton1 = new JButton("加入读者");
        JButton jButton2 = new JButton("加入写者");
        jButton1.addActionListener(e -> {
            new Thread(new Read(reader)).start();
            reader++;
        });
        jButton2.addActionListener(e -> {
            new Thread(new Write(writer)).start();
            writer++;
        });

        jPanel1.add(jButton1, BorderLayout.SOUTH);
        jPanel3.add(jButton2, BorderLayout.SOUTH);

        // 新增导出日志按钮
        JButton exportBtn = new JButton("导出日志为Excel");
        exportBtn.addActionListener(e -> {
            try {
                exportLogsToExcel();
            } catch (Exception ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(null, "导出失败：" + ex.getMessage());
            }
        });
        jPanel2.add(exportBtn, BorderLayout.SOUTH);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void insert1(String str)//读模块的gui部分
    {
        SimpleAttributeSet set = new SimpleAttributeSet();
        try {
            jTextPane1.getDocument().insertString(jTextPane1.getDocument().getLength(), str + "\n", set);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    public static void insert2(String str)//被访问文件模块的gui部分
    {
        SimpleAttributeSet set = new SimpleAttributeSet();
        try {
            jTextPane2.getDocument().insertString(jTextPane2.getDocument().getLength(), str + "\n", set);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    public static void insert3(String str)//写模块的gui部分
    {
        SimpleAttributeSet set = new SimpleAttributeSet();
        try {
            jTextPane3.getDocument().insertString(jTextPane3.getDocument().getLength(), str + "\n", set);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    public static void refresh() {
        jTextPane1.setText(null);
        jTextPane2.setText(null);
        jTextPane3.setText(null);

        for (String a : Re) {
            insert1("读者 " + a);
        }
        for (String b : ing) {
            insert2(b);
        }
        for (String c : Wr) {
            insert3("写者 " + c);
        }
    }

    public static void exportLogsToExcel() {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("日志导出");

        // 表头
        Row header = sheet.createRow(0);
        header.createCell(0).setCellValue("类型");
        header.createCell(1).setCellValue("日志内容");

        int rowIndex = 1;

        for (String log : Re) {
            Row row = sheet.createRow(rowIndex++);
            row.createCell(0).setCellValue("读者打算");
            row.createCell(1).setCellValue(log);
        }

        for (String log : ing) {
            Row row = sheet.createRow(rowIndex++);
            row.createCell(0).setCellValue("正在");
            row.createCell(1).setCellValue(log);
        }

        for (String log : Wr) {
            Row row = sheet.createRow(rowIndex++);
            row.createCell(0).setCellValue("写者打算");
            row.createCell(1).setCellValue(log);
        }

        // 自动列宽
        sheet.autoSizeColumn(0);
        sheet.autoSizeColumn(1);

        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("选择导出Excel文件路径");
        fileChooser.setSelectedFile(new java.io.File("日志导出.xlsx"));
        int userSelection = fileChooser.showSaveDialog(null);

        if (userSelection == JFileChooser.APPROVE_OPTION) {
            try (FileOutputStream out = new FileOutputStream(fileChooser.getSelectedFile())) {
                workbook.write(out);
                workbook.close();
                JOptionPane.showMessageDialog(null, "导出成功！");
            } catch (IOException e) {
                JOptionPane.showMessageDialog(null, "导出失败：" + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        int a = Integer.parseInt(JOptionPane.showInputDialog("请输入初始读者数量"));
        int b = Integer.parseInt(JOptionPane.showInputDialog("请输入初始写者数量"));
        new ReadAndWrite(a, b);
    }
}
